大家好~
延續昨天說的話題,
如果我們想修改 API 回傳的格式,
還要在每個 function 中個別修改那豈不是很麻煩嗎?
而今天要來實作的 API Resources 就能解決上述的問題囉~
首先先來建立我們 Message 的 Resource 吧!
php artisan make:resource Message
php artisan make:resource MessageCollection
輸入上面兩個指令後,
我們會得到兩個 Resource ,
為什麼要有兩個呢?
簡單來說,
以上面建立的兩個 Resource 為例:
app/Http/Resources/Message.php
app/Http/Resources/MessageCollection.php
兩個 Resource 負責的工作不太一樣喔!
在建立 Resource 時帶上 --collection 參數,
或是使用 Collection 當作名稱結尾,
都能夠建立 extends 了 ResourceCollection 的 Resource 喔~
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'content' => $this->content,
'updated_at' => $this->updated_at,
'user' => User::make($this->whenLoaded('user')),
];
}
這樣簡單 Resource 就完成囉!
簡單介紹一下,
基本格式大概是這樣的規則:
return [
'自定義 Key 值' => $this->Model屬性名稱,
];
那該如何用他轉換我們想回傳的資料呢?
首先先在要使用 Resource 的 Controller 內 use 他們吧。
use App\Http\Resources\Message as MessageResource;
use App\Http\Resources\MessageCollection;
以檢索單一筆留言為例,
我們原本是:
public function show($messageId)
{
$message = Message::with('user')->findOrFail($messageId);
return response($message, Response::HTTP_OK);
}
現在改成:
public function show($messageId)
{
$message = Message::with('user')->findOrFail($messageId);
return response(MessageResource::make($message), Response::HTTP_OK);
}
上面的例子是用當資料型態為 Model 時為例子,
那如果資料型態是 Collection 呢?
這是我們原本的查詢所有留言功能 return response 的方式:
public function index()
{
$messages = Message::with('user')->get();
return response($messages, Response::HTTP_OK);
}
只要改成:
public function index()
{
$messages = Message::with('user')->get();
// 方法 1.
return response(MessageCollection::make($messages), Response::HTTP_OK);
// 方法 2.
return response(MessageResource::collection($messages), Response::HTTP_OK);
}
方法1與方法2都可以回傳資料型態為 Collection 的資料喔!
成果預覽:
Resource 提供許多有趣且實用的用法,
本次範例無法一一介紹到,
像上方用到的 whenLoaded() 會判斷資料有沒有加載關聯,
若沒有加載關聯,
該 Key 就不會回傳。
這樣也可以避免查詢時發生「N+1」問題喔~
下圖就是沒加載 user 關聯時的回傳結果,
可以看到回傳格式中沒有出現 user 的 key。
Resource::collection( )
也可以處理 Collection 的資料。那麼今天就先這樣啦!
大家明天見~
若文章有任何問題,
還請大家不吝賜教!